﻿using Chaunce.FrameWork.NetCore.SysCore;
using Chaunce.FrameWork.NetCore.SysCore.Configuration;
using Chaunce.FrameWork.NetCore.SysCore.Infrastructure;
using Chaunce.Web.Core.Helpers;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Filters;
using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;

namespace Chaunce.Web.Core.Filters
{
    /// <summary>
    /// api执行时间监控
    /// </summary>
    public class BenchmarkActionFilter : IAsyncActionFilter
    {
        private static readonly ILogger logger = Log.ForContext<BenchmarkActionFilter>();

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var config = EngineContext.Current.Resolve<ChaunceConfig>();
            int requestWarning = config.RequestWarningThreshold < 3 ? 3 : config.RequestWarningThreshold;

            var stopWatch = new Stopwatch();
            stopWatch.Start();

            await next();

            stopWatch.Stop();
            //如果执行超过设定的阈值则记录日志
            long executeTime = stopWatch.ElapsedMilliseconds / 1000;
            if (executeTime >= requestWarning)
            {
                string requestBodyText = string.Empty;
                var request = context.HttpContext.Request;
                var method = request.Method.ToUpper();
                var url = UriHelper.GetDisplayUrl(request);
                var macName = Environment.MachineName;
                var requestIp = EngineContext.Current.Resolve<IWebHelper>().GetCurrentIpAddress();
                var bodyText = ActionFilterHelper.GetRequestBodyText(request);
                logger.Warning("请求时间超过阈值.执行时间:{0}秒.请求url:{1},请求Body:{2},请求IP:{3},服务器名称:{4}",
                    stopWatch.ElapsedMilliseconds / 1000, url, bodyText, requestIp, macName);
            }
            context.HttpContext.Response.Headers.Add(
                "x-time-elapsed",
                stopWatch.Elapsed.ToString());
        }
    }
}
